<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片裁剪导出PDF工具</title>
    <link rel="stylesheet" href="../css/cropper.min.css">
    <link rel="stylesheet" href="../css/all.min.css">
    <style>
        :root {
            --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            --cancel-color: #6c757d;
            --light-gray: #f8f9fa;
            --dark-gray: #343a40;
            --success-color: #28a745;
            --error-color: #dc3545;
            --box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }
        
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background-color: #f5f7fa;
            color: #333;
            line-height: 1.6;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 10px;
            box-shadow: var(--box-shadow);
            overflow: hidden;
            padding: 30px;
        }
        
        h2 {
            margin-bottom: 20px;
            color: var(--dark-gray);
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .upload-section, .crop-section, .preview-section {
            margin-bottom: 30px;
            padding: 20px;
            background: white;
            border-radius: 8px;
            box-shadow: var(--box-shadow);
        }
        
        .file-upload-wrapper {
            margin: 20px 0;
        }
        
        .file-upload-label {
            display: inline-block;
            padding: 12px 25px;
            background: var(--primary-gradient);
            color: white;
            border-radius: 50px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.3s ease;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
            display: flex;
            align-items: center;
            gap: 8px;
            width: fit-content;
        }
        
        .file-upload-label:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
        
        #image-upload {
            display: none;
        }
        
        .cropper-container {
            width: 100%;
            height: 400px;
            margin: 20px 0;
            position: relative;
            overflow: hidden;
            border-radius: 8px;
            box-shadow: var(--box-shadow);
        }
        
        #image-preview {
            max-width: 100%;
            display: block;
        }
        
        .ratio-buttons {
            display: flex;
            gap: 10px;
            margin-bottom: 10px;
            flex-wrap: wrap;
        }
        
        .ratio-btn {
            padding: 8px 15px;
            border: none;
            border-radius: 5px;
            background: var(--light-gray);
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 5px;
            font-size: 14px;
        }
        
        .ratio-btn.active {
            background: var(--primary-gradient);
            color: white;
        }
        
        .controls {
            display: flex;
            gap: 10px;
            margin-top: 10px;
            flex-wrap: wrap;
        }
        
        button {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .primary-btn {
            background: var(--primary-gradient);
            color: white;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
        }
        
        .primary-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }
        
        .cancel-btn {
            background: var(--cancel-color);
            color: white;
        }
        
        .cancel-btn:hover {
            background: #5a6268;
        }
        
        .preview-box {
            margin: 20px 0;
            padding: 20px;
            border-radius: 8px;
            background: var(--light-gray);
            box-shadow: var(--box-shadow);
            text-align: center;
        }
        
        .preview-image {
            max-width: 100%;
            max-height: 500px;
            display: block;
            margin: 0 auto;
            border-radius: 5px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        
        .status-message {
            padding: 10px 15px;
            border-radius: 5px;
            margin: 10px 0;
            display: none;
        }
        
        .success {
            background-color: rgba(40, 167, 69, 0.2);
            color: var(--success-color);
            border-left: 4px solid var(--success-color);
        }
        
        .error {
            background-color: rgba(220, 53, 69, 0.2);
            color: var(--error-color);
            border-left: 4px solid var(--error-color);
        }
        
        @media (max-width: 768px) {
            .container {
                padding: 15px;
            }
            
            .controls, .ratio-buttons {
                flex-direction: column;
            }
            
            button, .ratio-btn {
                width: 100%;
                justify-content: center;
            }
            
            .cropper-container {
                height: 300px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="upload-section">
            <h2><i class="fas fa-upload"></i>选择图片</h2>
            <p>请选择不超过5MB的图片，支持常见图片格式（如JPEG、PNG等）。</p>
            <div class="file-upload-wrapper">
                <label for="image-upload" class="file-upload-label">
                    <i class="fas fa-cloud-upload-alt"></i> 选择图片文件
                </label>
                <input type="file" id="image-upload" accept="image/*">
            </div>
            <div id="upload-status" class="status-message"></div>
        </div>
        
        <div class="crop-section" style="display: none;">
            <h2><i class="fas fa-cut"></i>裁剪图片</h2>
            <div class="ratio-buttons">
                <button class="ratio-btn" data-ratio="1"><i class="fas fa-square"></i> 1:1 (正方形)</button>
                <button class="ratio-btn" data-ratio="4/3"><i class="fas fa-tablet-alt"></i> 4:3</button>
                <button class="ratio-btn" data-ratio="16/9"><i class="fas fa-tv"></i> 16:9</button>
                <button class="ratio-btn" data-ratio="NaN"><i class="fas fa-vector-square"></i> 自由比例</button>
            </div>
            <div class="cropper-container">
                <img id="image-preview" src="">
            </div>
            <div class="controls">
                <button id="crop-btn" class="primary-btn"><i class="fas fa-check"></i> 确认裁剪</button>
                <button id="rotate-left-btn" class="primary-btn"><i class="fas fa-undo"></i> 向左旋转</button>
                <button id="rotate-right-btn" class="primary-btn"><i class="fas fa-redo"></i> 向右旋转</button>
                <button id="reset-btn" class="cancel-btn"><i class="fas fa-sync-alt"></i> 重置</button>
            </div>
        </div>
        
        <div class="preview-section" style="display: none;">
            <h2><i class="fas fa-eye"></i>预览并导出PDF</h2>
            <div class="preview-box">
                <h3><i class="fas fa-image"></i> 裁剪结果预览</h3>
                <img id="cropped-result" class="preview-image">
            </div>
            <div class="controls">
                <button id="export-pdf-btn" class="primary-btn"><i class="fas fa-file-pdf"></i> 导出PDF</button>
                <button id="new-image-btn" class="cancel-btn"><i class="fas fa-plus-circle"></i> 处理新图片</button>
            </div>
            <div id="export-status" class="status-message"></div>
        </div>
    </div>

    <!-- 引入必要的JS库 -->
    <script src="../js/cropper.min.js"></script>
    <script src="../js/jspdf.umd.min.js"></script>
    
    <script>
        // 初始化变量
        let cropper;
        let croppedImageBlob;
        
        // 等待DOM加载完成
        document.addEventListener('DOMContentLoaded', function() {
            // 获取DOM元素
            const imageUpload = document.getElementById('image-upload');
            const imagePreview = document.getElementById('image-preview');
            const cropSection = document.querySelector('.crop-section');
            const previewSection = document.querySelector('.preview-section');
            const croppedResult = document.getElementById('cropped-result');
            const cropBtn = document.getElementById('crop-btn');
            const rotateLeftBtn = document.getElementById('rotate-left-btn');
            const rotateRightBtn = document.getElementById('rotate-right-btn');
            const resetBtn = document.getElementById('reset-btn');
            const exportPdfBtn = document.getElementById('export-pdf-btn');
            const newImageBtn = document.getElementById('new-image-btn');
            const ratioButtons = document.querySelectorAll('.ratio-btn');
            const uploadStatus = document.getElementById('upload-status');
            const exportStatus = document.getElementById('export-status');
            
            // 图片选择事件
            imageUpload.addEventListener('change', function(e) {
                const file = e.target.files[0];
                if (file) {
                    // 检查文件类型
                    if (!file.type.match('image.*')) {
                        showStatus(uploadStatus, '请选择有效的图片文件', 'error');
                        return;
                    }
                    
                    // 检查文件大小 (限制5MB)
                    if (file.size > 5 * 1024 * 1024) {
                        showStatus(uploadStatus, '图片大小不能超过5MB', 'error');
                        return;
                    }
                    
                    const reader = new FileReader();
                    reader.onloadstart = function() {
                        showStatus(uploadStatus, '正在加载图片...', 'success');
                    };
                    reader.onload = function(event) {
                        imagePreview.src = event.target.result;
                        cropSection.style.display = 'block';
                        previewSection.style.display = 'none';
                        uploadStatus.style.display = 'none';
                        
                        // 初始化Cropper.js
                        if (cropper) {
                            cropper.destroy();
                        }
                        
                        cropper = new Cropper(imagePreview, {
                            aspectRatio: 1,
                            viewMode: 1,
                            autoCropArea: 0.8,
                            responsive: true,
                            guides: true,
                            center: true,
                            background: true,
                            movable: true,
                            rotatable: true,
                            scalable: true,
                            zoomable: true,
                            zoomOnTouch: true,
                            zoomOnWheel: true,
                            cropBoxMovable: true,
                            cropBoxResizable: true,
                            toggleDragModeOnDblclick: false,
                        });
                    };
                    reader.onerror = function() {
                        showStatus(uploadStatus, '图片加载失败，请重试', 'error');
                    };
                    reader.readAsDataURL(file);
                }
            });
            
            // 显示状态消息
            function showStatus(element, message, type) {
                element.textContent = message;
                element.className = `status-message ${type}`;
                element.style.display = 'block';
                
                // 3秒后自动隐藏
                if (type === 'success') {
                    setTimeout(() => {
                        element.style.display = 'none';
                    }, 3000);
                }
            }
            
            // 比例按钮点击事件
            ratioButtons.forEach(button => {
                button.addEventListener('click', function() {
                    // 移除所有active类
                    ratioButtons.forEach(btn => btn.classList.remove('active'));
                    // 给当前按钮添加active类
                    this.classList.add('active');
                    
                    const ratio = parseFloat(this.dataset.ratio);
                    if (isNaN(ratio)) {
                        cropper.setAspectRatio(NaN);
                    } else {
                        cropper.setAspectRatio(ratio);
                    }
                });
            });
            
            // 默认激活第一个比例按钮
            if (ratioButtons.length > 0) {
                ratioButtons[0].classList.add('active');
            }
            
            // 旋转按钮事件
            rotateLeftBtn.addEventListener('click', function() {
                cropper.rotate(-90);
            });
            
            rotateRightBtn.addEventListener('click', function() {
                cropper.rotate(90);
            });
            
            // 重置按钮事件
            resetBtn.addEventListener('click', function() {
                cropper.reset();
            });
            
            // 裁剪按钮事件
            cropBtn.addEventListener('click', function() {
                // 获取裁剪后的canvas
                const canvas = cropper.getCroppedCanvas({
                    width: 800,  // 设置输出宽度
                    height: 800, // 设置输出高度
                    minWidth: 256,
                    minHeight: 256,
                    maxWidth: 4096,
                    maxHeight: 4096,
                    fillColor: '#fff',
                    imageSmoothingEnabled: true,
                    imageSmoothingQuality: 'high',
                });
                
                if (!canvas) {
                    showStatus(uploadStatus, '裁剪失败，请重试', 'error');
                    return;
                }
                
                // 显示裁剪结果
                croppedResult.src = canvas.toDataURL('image/jpeg');
                
                // 转换为Blob对象以便后续使用
                canvas.toBlob(function(blob) {
                    croppedImageBlob = blob;
                    showStatus(exportStatus, '图片裁剪完成，可以导出PDF了', 'success');
                }, 'image/jpeg', 0.95);
                
                // 显示预览区域
                previewSection.style.display = 'block';
                cropSection.style.display = 'none';
            });
            
            // 生成时间戳文件名
            function getTimestampFilename() {
                const now = new Date();
                const year = now.getFullYear();
                const month = String(now.getMonth() + 1).padStart(2, '0');
                const day = String(now.getDate()).padStart(2, '0');
                const hours = String(now.getHours()).padStart(2, '0');
                const minutes = String(now.getMinutes()).padStart(2, '0');
                const seconds = String(now.getSeconds()).padStart(2, '0');
                
                return `${year}${month}${day}-${hours}${minutes}${seconds}.pdf`;
            }
            
            // 导出PDF按钮事件
            exportPdfBtn.addEventListener('click', function() {
                if (!croppedImageBlob) {
                    showStatus(exportStatus, '没有可导出的图片', 'error');
                    return;
                }
                
                showStatus(exportStatus, '正在生成PDF...', 'success');
                
                const reader = new FileReader();
                reader.onload = function(event) {
                    const imageData = event.target.result;
                    
                    // 使用jsPDF创建PDF
                    const { jsPDF } = window.jspdf;
                    const pdf = new jsPDF({
                        orientation: 'portrait',
                        unit: 'mm'
                    });
                    
                    // 获取图片尺寸
                    const img = new Image();
                    img.onload = function() {
                        // 计算在PDF中的尺寸 (A4尺寸: 210x297mm)
                        const pdfWidth = pdf.internal.pageSize.getWidth() - 20; // 留边距
                        const pdfHeight = (img.height * pdfWidth) / img.width;
                        
                        // 添加图片到PDF
                        pdf.addImage(imageData, 'JPEG', 10, 10, pdfWidth, pdfHeight);
                        
                        // 使用时间戳作为文件名
                        const filename = getTimestampFilename();
                        
                        // 保存PDF
                        pdf.save(filename);
                        
                        showStatus(exportStatus, 'PDF导出成功!', 'success');
                    };
                    img.onerror = function() {
                        showStatus(exportStatus, '图片加载失败，无法导出PDF', 'error');
                    };
                    img.src = imageData;
                };
                reader.onerror = function() {
                    showStatus(exportStatus, '文件读取失败，无法导出PDF', 'error');
                };
                reader.readAsDataURL(croppedImageBlob);
            });
            
            // 处理新图片按钮事件
            newImageBtn.addEventListener('click', function() {
                // 重置所有状态
                imageUpload.value = '';
                previewSection.style.display = 'none';
                cropSection.style.display = 'none';
                croppedResult.src = '';
                croppedImageBlob = null;
                uploadStatus.style.display = 'none';
                exportStatus.style.display = 'none';
                
                if (cropper) {
                    cropper.destroy();
                    cropper = null;
                }
            });
        });
    </script>
</body>
</html>
    